package com.bbs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bbs.common.Constants;
import com.bbs.common.ServiceResultEnum;
import com.bbs.entity.BBSUser;
import com.bbs.mapper.IBBSUserMapper;
import com.bbs.service.IBBSUserService;
import com.bbs.util.MD5Util;
import com.bbs.util.PatternUtil;
import com.bbs.util.StringUtil;
import com.bbs.util.SystemUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @PackageName: com.bbs.service.impl
 * @ClassName: BBSUserServiceImpl
 * @Description:
 * @Author: Rambo
 * @Data: 2024/6/2 23:22
 */
@Service
public class BBSUserServiceImpl implements IBBSUserService {
    @Autowired
    private IBBSUserMapper bbsUserMapper;

    /**
     * 用户注册方法
     * @param loginName 用户输入的登录名，用于匹配数据库或用户信息存储中的用户名。
     * @param password 用户输入密码，用MD5算法加密后用于匹配数据库或用户信息存储中的密码。
     * @param nickName 用户输入昵称，用于匹配数据库或用户信息存储中的昵称。
     * @return
     */
    @Override
    public String register(String loginName, String password, String verifyCode, String nickName, HttpSession httpSession) {
        // 1、判断参数是否为空及格式是否符合要求
        // 判断用户名是否为空
        if (StringUtil.isEmpty(loginName)) {
            return ServiceResultEnum.LOGIN_NAME_NULL.getResult();
        }
        // 判断密码是否为空
        if (StringUtil.isEmpty(password)) {
            return ServiceResultEnum.LOGIN_PASSWORD_NULL.getResult();
        }
        // 判断验证码是否为空
        if (StringUtil.isEmpty(verifyCode)) {
            return ServiceResultEnum.LOGIN_VERIFY_CODE_NULL.getResult();
        }
        // 判断登录名是否符合邮箱格式
        if (!PatternUtil.isEmail(loginName)) {
            return ServiceResultEnum.LOGIN_NAME_NOT_EMAIL.getResult();
        }

        // 2、判断验证码是否正确
        // 获取HttpSession中的验证码，并将其转换为字符串类型
        String sessionVerifyCode = httpSession.getAttribute(Constants.VERIFY_CODE_KEY) + "";
        // 判断HttpSession中验证码是否为空且与用户在页面输入的验证码进行比较
        if (StringUtil.isEmpty(sessionVerifyCode) || !sessionVerifyCode.equalsIgnoreCase(verifyCode)) {
            return ServiceResultEnum.LOGIN_VERIFY_CODE_ERROR.getResult();
        }

        // 3、根据用户名查询用户信息是否存在
        BBSUser bbsUser = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getLoginName, loginName)
        );
        if (bbsUser != null) {
            return ServiceResultEnum.SAME_LOGIN_NAME_EXIST.getResult();
        }

        // 4、未查询到用户信息进行注册
        BBSUser registerUser = new BBSUser();
        registerUser.setLoginName(loginName);
        registerUser.setNickName(nickName);
        //默认头像
        registerUser.setHeadImgUrl("/images/avatar/default.png");
        //默认介绍
        registerUser.setIntroduce("这个人很懒，什么都没留下~");
        //居住地
        registerUser.setLocation("未知");
        registerUser.setGender("未知");
        String passwordMD5 = MD5Util.MD5Encode(password, "UTF-8");
        registerUser.setPasswordMd5(passwordMD5);

        // 5、调用持久层插入数据
        if (bbsUserMapper.insert(registerUser) > 0) {
            return ServiceResultEnum.SUCCESS.getResult();
        }
        return ServiceResultEnum.DB_ERROR.getResult();
    }

    /**
     * 用户登录方法
     * @param loginName 用户输入的登录名，用于匹配数据库或用户信息存储中的用户名。
     * @param password 用户输入密码，用MD5算法加密后用于匹配数据库或用户信息存储中的密码。
     * @param httpSession HttpSession对象，用于登录成功后存储用户的会话信息。
     * @return
     */
    @Override
    public String login(String loginName, String password, String verifyCode, HttpSession httpSession) {
        // 1、判断参数是否为空及格式是否符合要求
        // 判断用户名是否为空
        if (StringUtil.isEmpty(loginName)) {
            return ServiceResultEnum.LOGIN_NAME_NULL.getResult();
        }
        // 判断密码是否为空
        if (StringUtil.isEmpty(password)) {
            return ServiceResultEnum.LOGIN_PASSWORD_NULL.getResult();
        }
        // 判断验证码是否为空
        if (StringUtil.isEmpty(verifyCode)) {
            return ServiceResultEnum.LOGIN_VERIFY_CODE_NULL.getResult();
        }
        // 判断登录名是否符合邮箱格式
        if (!PatternUtil.isEmail(loginName)) {
            return ServiceResultEnum.LOGIN_NAME_NOT_EMAIL.getResult();
        }

        // 2、判断验证码是否正确
        // 获取HttpSession中的验证码，并将其转换为字符串类型
        String sessionVerifyCode = httpSession.getAttribute(Constants.VERIFY_CODE_KEY) + "";
        // 判断HttpSession中验证码是否为空且与用户在页面输入的验证码进行比较
        if (StringUtil.isEmpty(sessionVerifyCode) || !sessionVerifyCode.equalsIgnoreCase(verifyCode)) {
            return ServiceResultEnum.LOGIN_VERIFY_CODE_ERROR.getResult();
        }

        // 3、根据用户名与密码查询用户信息
        // 将密码用MD5加密
        String passwordMD5 = MD5Util.MD5Encode(password, "UTF-8");
        BBSUser bbsUser = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getLoginName, loginName)
                        .eq(BBSUser::getPasswordMd5, passwordMD5)
        );

        // 4、判断用户是否存在
        if (bbsUser == null || httpSession == null ) {
            return ServiceResultEnum.LOGIN_ERROR.getResult();
        }

        // 5、用户存在，则更新用户登录信息
        //保存键值
        httpSession.setAttribute(Constants.USER_SESSION_KEY, bbsUser);
        //修改最近登录时间
        bbsUser.setLastLoginTime(new Date());
        // 更新数据库中的用户信息，只更新 user 对象中发生变化的字段
        if (bbsUserMapper.update(null,
                new UpdateWrapper<BBSUser>()
                        .eq("user_id", bbsUser.getUserId())
                        .set("last_login_time", bbsUser.getLastLoginTime())
        ) == 0) {
            return ServiceResultEnum.DB_ERROR.getResult();
        }

        return ServiceResultEnum.SUCCESS.getResult();
    }

    /**
     * 修改用户信息
     * @param bbsUser
     * @param httpSession
     * @return
     */
    @Override
    public Boolean updateUserInfo(BBSUser bbsUser, HttpSession httpSession) {
        //根据USER_SESSION_KEY键获取到Session中的用户对象
        BBSUser userTemp = (BBSUser) httpSession.getAttribute(Constants.USER_SESSION_KEY);
        //通过用户对象id获取查询用户原来的信息
        BBSUser userFromDB = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, userTemp.getUserId())
        );
        //当前用户非空且状态正常才可以进行更改
        if (userFromDB != null && userFromDB.getUserStatus().intValue() == 0) {
            //通过自定义的SystemUtils中的cleanString()方法消除字符串中不符合规则的字符
            userFromDB.setIntroduce(SystemUtil.cleanString(bbsUser.getIntroduce()));
            userFromDB.setLocation(SystemUtil.cleanString(bbsUser.getLocation()));
            userFromDB.setGender(SystemUtil.cleanString(bbsUser.getGender()));
            userFromDB.setNickName(SystemUtil.cleanString(bbsUser.getNickName()));
            if (bbsUserMapper.update(userTemp,
                    new UpdateWrapper<BBSUser>()
                            .eq("user_id", userFromDB.getUserId())
            ) > 0) {
                httpSession.setAttribute(Constants.USER_SESSION_KEY, userFromDB);
                return true;
            }
        }
        return false;
    }

    /**
     * 修改用户头像
     * @param user
     * @param httpSession
     * @return
     */
    @Override
    public Boolean updateUserHeadImg(BBSUser user, HttpSession httpSession) {
        //通过用户ID获取用户头像
        BBSUser userFromDB = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, user.getUserId())
        );
        //当前用户非空且状态正常才可以进行更改
        if (userFromDB != null && userFromDB.getUserStatus().intValue() == 0) {
            //通过自定义的SystemUtils中的cleanString()方法消除字符串中不符合规则的字符
            userFromDB.setHeadImgUrl(user.getHeadImgUrl());
            if (bbsUserMapper.update(user,
                    new UpdateWrapper<BBSUser>()
                            .eq("user_id", userFromDB.getUserId())
            ) > 0) {
                httpSession.setAttribute(Constants.USER_SESSION_KEY, userFromDB);
                return true;
            }
        }
        return false;
    }

    /**
     * 修改用户密码
     * @param userId
     * @param newPassword
     * @param httpSession
     * @return
     */
    public Boolean updateUserPassword(Long userId, String newPassword, HttpSession httpSession) {
        BBSUser userFromDB = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, userId)
        );
        if (userFromDB != null && userFromDB.getUserStatus().intValue() == 0) {
            //将新密码用MD5加密
            String passwordMD5 = MD5Util.MD5Encode(newPassword, "UTF-8");
            userFromDB.setPasswordMd5(passwordMD5);
            if (bbsUserMapper.update(userFromDB,
                    new UpdateWrapper<BBSUser>()
                            .eq("user_id", userFromDB.getUserId())
                            .set("password_md5",userFromDB.getPasswordMd5())
            ) >0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据用户ID获取用户信息
     * @param userId 用户Id
     * @return
     */
    @Override
    public BBSUser getUserById(Long userId) {
        BBSUser bbsUser = bbsUserMapper.selectOne(
                new LambdaQueryWrapper<BBSUser>()
                        .eq(BBSUser::getUserId, userId)
        );

        return bbsUser;
    }
}
